/*
 * Copyright (c) 2021, Peter Abeles. All Rights Reserved.
 *
 * This file is part of BoofCV (http://boofcv.org).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package boofcv.alg.filter.convolve;

import boofcv.alg.filter.convolve.border.ConvolveJustBorder_General_SB;
import boofcv.alg.filter.convolve.normalized.ConvolveNormalizedNaive_IL;
import boofcv.alg.filter.convolve.normalized.ConvolveNormalizedNaive_SB;
import boofcv.alg.filter.convolve.normalized.ConvolveNormalized_JustBorder_IL;
import boofcv.alg.filter.convolve.normalized.ConvolveNormalized_JustBorder_SB;
import boofcv.alg.filter.kernel.KernelMath;
import boofcv.struct.border.ImageBorder_F32;
import boofcv.struct.border.ImageBorder_F64;
import boofcv.struct.border.ImageBorder_S32;
import boofcv.struct.convolve.*;
import boofcv.struct.image.*;

/**
 * <p>
 * Convolves a kernel across an image and scales the kernel such that the sum of the portion inside
 * the image sums up to one.
 * </p>
 * <p>Automatically generated by GenerateConvolveImageNormalized. DO NOT MODIFY</p>
 *
 * @author Peter Abeles
 */
@SuppressWarnings({"ForLoopReplaceableByForEach", "unchecked"})
public class ConvolveImageNormalized {

	/**
	 * Performs a horizontal 1D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void horizontal( Kernel1D_F32 kernel, GrayF32 src, GrayF32 dst ) {
		dst.reshape(src.width,src.height);

		if( BOverrideConvolveImageNormalized.invokeNativeHorizontal(kernel,src,dst) )
			return;

		if( kernel.width >= src.width ) {
			ConvolveNormalizedNaive_SB.horizontal(kernel, src, dst);
		} else {
			if( Math.abs(kernel.computeSum() - 1.0f) > 1e-4f ) {
				Kernel1D_F32 k = kernel.copy();
				KernelMath.normalizeSumToOne(k);
				kernel = k;
			}
			ConvolveImageNoBorder.horizontal(kernel,src,dst);
			ConvolveNormalized_JustBorder_SB.horizontal(kernel, src, dst);
		}
	}

	/**
	 * Performs a vertical 1D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void vertical( Kernel1D_F32 kernel, GrayF32 src, GrayF32 dst ) {
		dst.reshape(src.width,src.height);

		if( BOverrideConvolveImageNormalized.invokeNativeVertical(kernel,src,dst) )
			return;

		if( kernel.width >= src.height ) {
			ConvolveNormalizedNaive_SB.vertical(kernel, src, dst);
		} else {
			if( Math.abs(kernel.computeSum() - 1.0f) > 1e-4f ) {
				Kernel1D_F32 k = kernel.copy();
				KernelMath.normalizeSumToOne(k);
				kernel = k;
			}
			ConvolveImageNoBorder.vertical(kernel,src,dst);
			ConvolveNormalized_JustBorder_SB.vertical(kernel, src, dst);
		}
	}

	/**
	 * Performs a 2D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void convolve( Kernel2D_F32 kernel, GrayF32 src, GrayF32 dst ) {
		dst.reshape(src.width,src.height);

		if( BOverrideConvolveImageNormalized.invokeNativeConvolve(kernel,src,dst) )
			return;

		if( kernel.width >= src.width || kernel.width >= src.height ) {
			ConvolveNormalizedNaive_SB.convolve(kernel, src, dst);
		} else {
			if( Math.abs(kernel.computeSum() - 1.0f) > 1e-4f ) {
				Kernel2D_F32 k = kernel.copy();
				KernelMath.normalizeSumToOne(k);
				kernel = k;
			}
			ConvolveImageNoBorder.convolve(kernel,src,dst);
			ConvolveNormalized_JustBorder_SB.convolve(kernel, src, dst);
		}
	}

	/**
	 * Performs a horizontal 1D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void horizontal( Kernel1D_F32 kernel, GrayF32 src, GrayF32 dst, ImageBorder_F32 bsrc ) {
		dst.reshape(src.width,src.height);

		//if( BOverrideConvolveImageNormalized.invokeNativeHorizontal(kernel,src,dst) )
		//	return;

		bsrc.setImage(src);

		if( kernel.width >= src.width ) {
			ConvolveNormalizedNaive_SB.horizontal(kernel, src, dst, bsrc);
		} else {
			if( Math.abs(kernel.computeSum() - 1.0f) > 1e-4f ) {
				Kernel1D_F32 k = kernel.copy();
				KernelMath.normalizeSumToOne(k);
				kernel = k;
			}
			ConvolveImageNoBorder.horizontal(kernel,src,dst);
			ConvolveJustBorder_General_SB.horizontal(kernel, bsrc, dst);
		}
	}

	/**
	 * Performs a vertical 1D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void vertical( Kernel1D_F32 kernel, GrayF32 src, GrayF32 dst, ImageBorder_F32 bsrc ) {
		dst.reshape(src.width,src.height);

		//if( BOverrideConvolveImageNormalized.invokeNativeVertical(kernel,src,dst) )
		//	return;

		bsrc.setImage(src);

		if( kernel.width >= src.height ) {
			ConvolveNormalizedNaive_SB.vertical(kernel, src, dst, bsrc);
		} else {
			if( Math.abs(kernel.computeSum() - 1.0f) > 1e-4f ) {
				Kernel1D_F32 k = kernel.copy();
				KernelMath.normalizeSumToOne(k);
				kernel = k;
			}
			ConvolveImageNoBorder.vertical(kernel,src,dst);
			ConvolveJustBorder_General_SB.vertical(kernel, bsrc, dst);
		}
	}

	/**
	 * Performs a 2D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void convolve( Kernel2D_F32 kernel, GrayF32 src, GrayF32 dst, ImageBorder_F32 bsrc ) {
		dst.reshape(src.width,src.height);

		//if( BOverrideConvolveImageNormalized.invokeNativeConvolve(kernel,src,dst) )
		//	return;

		bsrc.setImage(src);

		if( kernel.width >= src.width || kernel.width >= src.height ) {
			ConvolveNormalizedNaive_SB.convolve(kernel, src, dst, bsrc);
		} else {
			if( Math.abs(kernel.computeSum() - 1.0f) > 1e-4f ) {
				Kernel2D_F32 k = kernel.copy();
				KernelMath.normalizeSumToOne(k);
				kernel = k;
			}
			ConvolveImageNoBorder.convolve(kernel,src,dst);
			ConvolveJustBorder_General_SB.convolve(kernel, bsrc, dst);
		}
	}

	/**
	 * Performs a horizontal 1D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void horizontal( Kernel1D_F32 kernel, InterleavedF32 src, InterleavedF32 dst ) {
		dst.reshape(src.width,src.height);

		if( BOverrideConvolveImageNormalized.invokeNativeHorizontal(kernel,src,dst) )
			return;

		if( kernel.width >= src.width ) {
			ConvolveNormalizedNaive_IL.horizontal(kernel, src, dst);
		} else {
			if( Math.abs(kernel.computeSum() - 1.0f) > 1e-4f ) {
				Kernel1D_F32 k = kernel.copy();
				KernelMath.normalizeSumToOne(k);
				kernel = k;
			}
			ConvolveImageNoBorder.horizontal(kernel,src,dst);
			ConvolveNormalized_JustBorder_IL.horizontal(kernel, src, dst);
		}
	}

	/**
	 * Performs a vertical 1D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void vertical( Kernel1D_F32 kernel, InterleavedF32 src, InterleavedF32 dst ) {
		dst.reshape(src.width,src.height);

		if( BOverrideConvolveImageNormalized.invokeNativeVertical(kernel,src,dst) )
			return;

		if( kernel.width >= src.height ) {
			ConvolveNormalizedNaive_IL.vertical(kernel, src, dst);
		} else {
			if( Math.abs(kernel.computeSum() - 1.0f) > 1e-4f ) {
				Kernel1D_F32 k = kernel.copy();
				KernelMath.normalizeSumToOne(k);
				kernel = k;
			}
			ConvolveImageNoBorder.vertical(kernel,src,dst);
			ConvolveNormalized_JustBorder_IL.vertical(kernel, src, dst);
		}
	}

	/**
	 * Performs a 2D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void convolve( Kernel2D_F32 kernel, InterleavedF32 src, InterleavedF32 dst ) {
		dst.reshape(src.width,src.height);

		if( BOverrideConvolveImageNormalized.invokeNativeConvolve(kernel,src,dst) )
			return;

		if( kernel.width >= src.width || kernel.width >= src.height ) {
			ConvolveNormalizedNaive_IL.convolve(kernel, src, dst);
		} else {
			if( Math.abs(kernel.computeSum() - 1.0f) > 1e-4f ) {
				Kernel2D_F32 k = kernel.copy();
				KernelMath.normalizeSumToOne(k);
				kernel = k;
			}
			ConvolveImageNoBorder.convolve(kernel,src,dst);
			ConvolveNormalized_JustBorder_IL.convolve(kernel, src, dst);
		}
	}

	/**
	 * Performs a horizontal 1D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void horizontal( Kernel1D_F64 kernel, GrayF64 src, GrayF64 dst ) {
		dst.reshape(src.width,src.height);

		if( BOverrideConvolveImageNormalized.invokeNativeHorizontal(kernel,src,dst) )
			return;

		if( kernel.width >= src.width ) {
			ConvolveNormalizedNaive_SB.horizontal(kernel, src, dst);
		} else {
			if( Math.abs(kernel.computeSum() - 1.0f) > 1e-4f ) {
				Kernel1D_F64 k = kernel.copy();
				KernelMath.normalizeSumToOne(k);
				kernel = k;
			}
			ConvolveImageNoBorder.horizontal(kernel,src,dst);
			ConvolveNormalized_JustBorder_SB.horizontal(kernel, src, dst);
		}
	}

	/**
	 * Performs a vertical 1D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void vertical( Kernel1D_F64 kernel, GrayF64 src, GrayF64 dst ) {
		dst.reshape(src.width,src.height);

		if( BOverrideConvolveImageNormalized.invokeNativeVertical(kernel,src,dst) )
			return;

		if( kernel.width >= src.height ) {
			ConvolveNormalizedNaive_SB.vertical(kernel, src, dst);
		} else {
			if( Math.abs(kernel.computeSum() - 1.0f) > 1e-4f ) {
				Kernel1D_F64 k = kernel.copy();
				KernelMath.normalizeSumToOne(k);
				kernel = k;
			}
			ConvolveImageNoBorder.vertical(kernel,src,dst);
			ConvolveNormalized_JustBorder_SB.vertical(kernel, src, dst);
		}
	}

	/**
	 * Performs a 2D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void convolve( Kernel2D_F64 kernel, GrayF64 src, GrayF64 dst ) {
		dst.reshape(src.width,src.height);

		if( BOverrideConvolveImageNormalized.invokeNativeConvolve(kernel,src,dst) )
			return;

		if( kernel.width >= src.width || kernel.width >= src.height ) {
			ConvolveNormalizedNaive_SB.convolve(kernel, src, dst);
		} else {
			if( Math.abs(kernel.computeSum() - 1.0f) > 1e-4f ) {
				Kernel2D_F64 k = kernel.copy();
				KernelMath.normalizeSumToOne(k);
				kernel = k;
			}
			ConvolveImageNoBorder.convolve(kernel,src,dst);
			ConvolveNormalized_JustBorder_SB.convolve(kernel, src, dst);
		}
	}

	/**
	 * Performs a horizontal 1D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void horizontal( Kernel1D_F64 kernel, GrayF64 src, GrayF64 dst, ImageBorder_F64 bsrc ) {
		dst.reshape(src.width,src.height);

		//if( BOverrideConvolveImageNormalized.invokeNativeHorizontal(kernel,src,dst) )
		//	return;

		bsrc.setImage(src);

		if( kernel.width >= src.width ) {
			ConvolveNormalizedNaive_SB.horizontal(kernel, src, dst, bsrc);
		} else {
			if( Math.abs(kernel.computeSum() - 1.0f) > 1e-4f ) {
				Kernel1D_F64 k = kernel.copy();
				KernelMath.normalizeSumToOne(k);
				kernel = k;
			}
			ConvolveImageNoBorder.horizontal(kernel,src,dst);
			ConvolveJustBorder_General_SB.horizontal(kernel, bsrc, dst);
		}
	}

	/**
	 * Performs a vertical 1D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void vertical( Kernel1D_F64 kernel, GrayF64 src, GrayF64 dst, ImageBorder_F64 bsrc ) {
		dst.reshape(src.width,src.height);

		//if( BOverrideConvolveImageNormalized.invokeNativeVertical(kernel,src,dst) )
		//	return;

		bsrc.setImage(src);

		if( kernel.width >= src.height ) {
			ConvolveNormalizedNaive_SB.vertical(kernel, src, dst, bsrc);
		} else {
			if( Math.abs(kernel.computeSum() - 1.0f) > 1e-4f ) {
				Kernel1D_F64 k = kernel.copy();
				KernelMath.normalizeSumToOne(k);
				kernel = k;
			}
			ConvolveImageNoBorder.vertical(kernel,src,dst);
			ConvolveJustBorder_General_SB.vertical(kernel, bsrc, dst);
		}
	}

	/**
	 * Performs a 2D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void convolve( Kernel2D_F64 kernel, GrayF64 src, GrayF64 dst, ImageBorder_F64 bsrc ) {
		dst.reshape(src.width,src.height);

		//if( BOverrideConvolveImageNormalized.invokeNativeConvolve(kernel,src,dst) )
		//	return;

		bsrc.setImage(src);

		if( kernel.width >= src.width || kernel.width >= src.height ) {
			ConvolveNormalizedNaive_SB.convolve(kernel, src, dst, bsrc);
		} else {
			if( Math.abs(kernel.computeSum() - 1.0f) > 1e-4f ) {
				Kernel2D_F64 k = kernel.copy();
				KernelMath.normalizeSumToOne(k);
				kernel = k;
			}
			ConvolveImageNoBorder.convolve(kernel,src,dst);
			ConvolveJustBorder_General_SB.convolve(kernel, bsrc, dst);
		}
	}

	/**
	 * Performs a horizontal 1D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void horizontal( Kernel1D_F64 kernel, InterleavedF64 src, InterleavedF64 dst ) {
		dst.reshape(src.width,src.height);

		if( BOverrideConvolveImageNormalized.invokeNativeHorizontal(kernel,src,dst) )
			return;

		if( kernel.width >= src.width ) {
			ConvolveNormalizedNaive_IL.horizontal(kernel, src, dst);
		} else {
			if( Math.abs(kernel.computeSum() - 1.0f) > 1e-4f ) {
				Kernel1D_F64 k = kernel.copy();
				KernelMath.normalizeSumToOne(k);
				kernel = k;
			}
			ConvolveImageNoBorder.horizontal(kernel,src,dst);
			ConvolveNormalized_JustBorder_IL.horizontal(kernel, src, dst);
		}
	}

	/**
	 * Performs a vertical 1D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void vertical( Kernel1D_F64 kernel, InterleavedF64 src, InterleavedF64 dst ) {
		dst.reshape(src.width,src.height);

		if( BOverrideConvolveImageNormalized.invokeNativeVertical(kernel,src,dst) )
			return;

		if( kernel.width >= src.height ) {
			ConvolveNormalizedNaive_IL.vertical(kernel, src, dst);
		} else {
			if( Math.abs(kernel.computeSum() - 1.0f) > 1e-4f ) {
				Kernel1D_F64 k = kernel.copy();
				KernelMath.normalizeSumToOne(k);
				kernel = k;
			}
			ConvolveImageNoBorder.vertical(kernel,src,dst);
			ConvolveNormalized_JustBorder_IL.vertical(kernel, src, dst);
		}
	}

	/**
	 * Performs a 2D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void convolve( Kernel2D_F64 kernel, InterleavedF64 src, InterleavedF64 dst ) {
		dst.reshape(src.width,src.height);

		if( BOverrideConvolveImageNormalized.invokeNativeConvolve(kernel,src,dst) )
			return;

		if( kernel.width >= src.width || kernel.width >= src.height ) {
			ConvolveNormalizedNaive_IL.convolve(kernel, src, dst);
		} else {
			if( Math.abs(kernel.computeSum() - 1.0f) > 1e-4f ) {
				Kernel2D_F64 k = kernel.copy();
				KernelMath.normalizeSumToOne(k);
				kernel = k;
			}
			ConvolveImageNoBorder.convolve(kernel,src,dst);
			ConvolveNormalized_JustBorder_IL.convolve(kernel, src, dst);
		}
	}

	/**
	 * Performs a horizontal 1D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void horizontal( Kernel1D_S32 kernel, GrayU8 src, GrayI8 dst ) {
		dst.reshape(src.width,src.height);

		if( BOverrideConvolveImageNormalized.invokeNativeHorizontal(kernel,src,dst) )
			return;

		if( kernel.width >= src.width ) {
			ConvolveNormalizedNaive_SB.horizontal(kernel, src, dst);
		} else {
			ConvolveImageNoBorder.horizontal(kernel, src, dst, kernel.computeSum());
			ConvolveNormalized_JustBorder_SB.horizontal(kernel, src, dst);
		}
	}

	/**
	 * Performs a vertical 1D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void vertical( Kernel1D_S32 kernel, GrayU8 src, GrayI8 dst ) {
		dst.reshape(src.width,src.height);

		if( BOverrideConvolveImageNormalized.invokeNativeVertical(kernel,src,dst) )
			return;

		if( kernel.width >= src.height ) {
			ConvolveNormalizedNaive_SB.vertical(kernel, src, dst);
		} else {
			ConvolveImageNoBorder.vertical(kernel, src, dst, kernel.computeSum(), null);
			ConvolveNormalized_JustBorder_SB.vertical(kernel, src, dst);
		}
	}

	/**
	 * Performs a 2D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void convolve( Kernel2D_S32 kernel, GrayU8 src, GrayI8 dst ) {
		dst.reshape(src.width,src.height);

		if( BOverrideConvolveImageNormalized.invokeNativeConvolve(kernel,src,dst) )
			return;

		if( kernel.width >= src.width || kernel.width >= src.height ) {
			ConvolveNormalizedNaive_SB.convolve(kernel, src, dst);
		} else {
			ConvolveImageNoBorder.convolve(kernel, src, dst, kernel.computeSum(), null);
			ConvolveNormalized_JustBorder_SB.convolve(kernel, src, dst);
		}
	}

	/**
	 * Performs a horizontal 1D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void horizontal( Kernel1D_S32 kernel, GrayU8 src, GrayI8 dst, ImageBorder_S32<GrayU8> bsrc ) {
		dst.reshape(src.width,src.height);

		//if( BOverrideConvolveImageNormalized.invokeNativeHorizontal(kernel,src,dst) )
		//	return;

		bsrc.setImage(src);

		if( kernel.width >= src.width ) {
			ConvolveNormalizedNaive_SB.horizontal(kernel, src, dst, bsrc);
		} else {
			ConvolveImageNoBorder.horizontal(kernel, src, dst, kernel.computeSum());
			ConvolveJustBorder_General_SB.horizontal(kernel, bsrc, dst, kernel.computeSum());
		}
	}

	/**
	 * Performs a vertical 1D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void vertical( Kernel1D_S32 kernel, GrayU8 src, GrayI8 dst, ImageBorder_S32<GrayU8> bsrc ) {
		dst.reshape(src.width,src.height);

		//if( BOverrideConvolveImageNormalized.invokeNativeVertical(kernel,src,dst) )
		//	return;

		bsrc.setImage(src);

		if( kernel.width >= src.height ) {
			ConvolveNormalizedNaive_SB.vertical(kernel, src, dst, bsrc);
		} else {
			ConvolveImageNoBorder.vertical(kernel, src, dst, kernel.computeSum(), null);
			ConvolveJustBorder_General_SB.vertical(kernel, bsrc, dst, kernel.computeSum());
		}
	}

	/**
	 * Performs a 2D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void convolve( Kernel2D_S32 kernel, GrayU8 src, GrayI8 dst, ImageBorder_S32<GrayU8> bsrc ) {
		dst.reshape(src.width,src.height);

		//if( BOverrideConvolveImageNormalized.invokeNativeConvolve(kernel,src,dst) )
		//	return;

		bsrc.setImage(src);

		if( kernel.width >= src.width || kernel.width >= src.height ) {
			ConvolveNormalizedNaive_SB.convolve(kernel, src, dst, bsrc);
		} else {
			ConvolveImageNoBorder.convolve(kernel, src, dst, kernel.computeSum(), null);
			ConvolveJustBorder_General_SB.convolve(kernel, bsrc, dst, kernel.computeSum());
		}
	}

	/**
	 * Performs a horizontal 1D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void horizontal( Kernel1D_S32 kernel, InterleavedU8 src, InterleavedI8 dst ) {
		dst.reshape(src.width,src.height);

		if( BOverrideConvolveImageNormalized.invokeNativeHorizontal(kernel,src,dst) )
			return;

		if( kernel.width >= src.width ) {
			ConvolveNormalizedNaive_IL.horizontal(kernel, src, dst);
		} else {
			ConvolveImageNoBorder.horizontal(kernel, src, dst, kernel.computeSum());
			ConvolveNormalized_JustBorder_IL.horizontal(kernel, src, dst);
		}
	}

	/**
	 * Performs a vertical 1D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void vertical( Kernel1D_S32 kernel, InterleavedU8 src, InterleavedI8 dst ) {
		dst.reshape(src.width,src.height);

		if( BOverrideConvolveImageNormalized.invokeNativeVertical(kernel,src,dst) )
			return;

		if( kernel.width >= src.height ) {
			ConvolveNormalizedNaive_IL.vertical(kernel, src, dst);
		} else {
			ConvolveImageNoBorder.vertical(kernel, src, dst, kernel.computeSum());
			ConvolveNormalized_JustBorder_IL.vertical(kernel, src, dst);
		}
	}

	/**
	 * Performs a 2D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void convolve( Kernel2D_S32 kernel, InterleavedU8 src, InterleavedI8 dst ) {
		dst.reshape(src.width,src.height);

		if( BOverrideConvolveImageNormalized.invokeNativeConvolve(kernel,src,dst) )
			return;

		if( kernel.width >= src.width || kernel.width >= src.height ) {
			ConvolveNormalizedNaive_IL.convolve(kernel, src, dst);
		} else {
			ConvolveImageNoBorder.convolve(kernel, src, dst, kernel.computeSum());
			ConvolveNormalized_JustBorder_IL.convolve(kernel, src, dst);
		}
	}

	/**
	 * Performs a horizontal 1D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void horizontal( Kernel1D_S32 kernel, GrayS16 src, GrayI16 dst ) {
		dst.reshape(src.width,src.height);

		if( BOverrideConvolveImageNormalized.invokeNativeHorizontal(kernel,src,dst) )
			return;

		if( kernel.width >= src.width ) {
			ConvolveNormalizedNaive_SB.horizontal(kernel, src, dst);
		} else {
			ConvolveImageNoBorder.horizontal(kernel, src, dst, kernel.computeSum());
			ConvolveNormalized_JustBorder_SB.horizontal(kernel, src, dst);
		}
	}

	/**
	 * Performs a vertical 1D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void vertical( Kernel1D_S32 kernel, GrayS16 src, GrayI16 dst ) {
		dst.reshape(src.width,src.height);

		if( BOverrideConvolveImageNormalized.invokeNativeVertical(kernel,src,dst) )
			return;

		if( kernel.width >= src.height ) {
			ConvolveNormalizedNaive_SB.vertical(kernel, src, dst);
		} else {
			ConvolveImageNoBorder.vertical(kernel, src, dst, kernel.computeSum(), null);
			ConvolveNormalized_JustBorder_SB.vertical(kernel, src, dst);
		}
	}

	/**
	 * Performs a 2D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void convolve( Kernel2D_S32 kernel, GrayS16 src, GrayI16 dst ) {
		dst.reshape(src.width,src.height);

		if( BOverrideConvolveImageNormalized.invokeNativeConvolve(kernel,src,dst) )
			return;

		if( kernel.width >= src.width || kernel.width >= src.height ) {
			ConvolveNormalizedNaive_SB.convolve(kernel, src, dst);
		} else {
			ConvolveImageNoBorder.convolve(kernel, src, dst, kernel.computeSum(), null);
			ConvolveNormalized_JustBorder_SB.convolve(kernel, src, dst);
		}
	}

	/**
	 * Performs a horizontal 1D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void horizontal( Kernel1D_S32 kernel, GrayS16 src, GrayI16 dst, ImageBorder_S32<GrayS16> bsrc ) {
		dst.reshape(src.width,src.height);

		//if( BOverrideConvolveImageNormalized.invokeNativeHorizontal(kernel,src,dst) )
		//	return;

		bsrc.setImage(src);

		if( kernel.width >= src.width ) {
			ConvolveNormalizedNaive_SB.horizontal(kernel, src, dst, bsrc);
		} else {
			ConvolveImageNoBorder.horizontal(kernel, src, dst, kernel.computeSum());
			ConvolveJustBorder_General_SB.horizontal(kernel, bsrc, dst, kernel.computeSum());
		}
	}

	/**
	 * Performs a vertical 1D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void vertical( Kernel1D_S32 kernel, GrayS16 src, GrayI16 dst, ImageBorder_S32<GrayS16> bsrc ) {
		dst.reshape(src.width,src.height);

		//if( BOverrideConvolveImageNormalized.invokeNativeVertical(kernel,src,dst) )
		//	return;

		bsrc.setImage(src);

		if( kernel.width >= src.height ) {
			ConvolveNormalizedNaive_SB.vertical(kernel, src, dst, bsrc);
		} else {
			ConvolveImageNoBorder.vertical(kernel, src, dst, kernel.computeSum(), null);
			ConvolveJustBorder_General_SB.vertical(kernel, bsrc, dst, kernel.computeSum());
		}
	}

	/**
	 * Performs a 2D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void convolve( Kernel2D_S32 kernel, GrayS16 src, GrayI16 dst, ImageBorder_S32<GrayS16> bsrc ) {
		dst.reshape(src.width,src.height);

		//if( BOverrideConvolveImageNormalized.invokeNativeConvolve(kernel,src,dst) )
		//	return;

		bsrc.setImage(src);

		if( kernel.width >= src.width || kernel.width >= src.height ) {
			ConvolveNormalizedNaive_SB.convolve(kernel, src, dst, bsrc);
		} else {
			ConvolveImageNoBorder.convolve(kernel, src, dst, kernel.computeSum(), null);
			ConvolveJustBorder_General_SB.convolve(kernel, bsrc, dst, kernel.computeSum());
		}
	}

	/**
	 * Performs a horizontal 1D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void horizontal( Kernel1D_S32 kernel, InterleavedS16 src, InterleavedI16 dst ) {
		dst.reshape(src.width,src.height);

		if( BOverrideConvolveImageNormalized.invokeNativeHorizontal(kernel,src,dst) )
			return;

		if( kernel.width >= src.width ) {
			ConvolveNormalizedNaive_IL.horizontal(kernel, src, dst);
		} else {
			ConvolveImageNoBorder.horizontal(kernel, src, dst, kernel.computeSum());
			ConvolveNormalized_JustBorder_IL.horizontal(kernel, src, dst);
		}
	}

	/**
	 * Performs a vertical 1D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void vertical( Kernel1D_S32 kernel, InterleavedS16 src, InterleavedI16 dst ) {
		dst.reshape(src.width,src.height);

		if( BOverrideConvolveImageNormalized.invokeNativeVertical(kernel,src,dst) )
			return;

		if( kernel.width >= src.height ) {
			ConvolveNormalizedNaive_IL.vertical(kernel, src, dst);
		} else {
			ConvolveImageNoBorder.vertical(kernel, src, dst, kernel.computeSum());
			ConvolveNormalized_JustBorder_IL.vertical(kernel, src, dst);
		}
	}

	/**
	 * Performs a 2D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void convolve( Kernel2D_S32 kernel, InterleavedS16 src, InterleavedI16 dst ) {
		dst.reshape(src.width,src.height);

		if( BOverrideConvolveImageNormalized.invokeNativeConvolve(kernel,src,dst) )
			return;

		if( kernel.width >= src.width || kernel.width >= src.height ) {
			ConvolveNormalizedNaive_IL.convolve(kernel, src, dst);
		} else {
			ConvolveImageNoBorder.convolve(kernel, src, dst, kernel.computeSum());
			ConvolveNormalized_JustBorder_IL.convolve(kernel, src, dst);
		}
	}

	/**
	 * Performs a horizontal 1D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void horizontal( Kernel1D_S32 kernel, GrayU16 src, GrayI16 dst ) {
		dst.reshape(src.width,src.height);

		if( BOverrideConvolveImageNormalized.invokeNativeHorizontal(kernel,src,dst) )
			return;

		if( kernel.width >= src.width ) {
			ConvolveNormalizedNaive_SB.horizontal(kernel, src, dst);
		} else {
			ConvolveImageNoBorder.horizontal(kernel, src, dst, kernel.computeSum());
			ConvolveNormalized_JustBorder_SB.horizontal(kernel, src, dst);
		}
	}

	/**
	 * Performs a vertical 1D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void vertical( Kernel1D_S32 kernel, GrayU16 src, GrayI16 dst ) {
		dst.reshape(src.width,src.height);

		if( BOverrideConvolveImageNormalized.invokeNativeVertical(kernel,src,dst) )
			return;

		if( kernel.width >= src.height ) {
			ConvolveNormalizedNaive_SB.vertical(kernel, src, dst);
		} else {
			ConvolveImageNoBorder.vertical(kernel, src, dst, kernel.computeSum(), null);
			ConvolveNormalized_JustBorder_SB.vertical(kernel, src, dst);
		}
	}

	/**
	 * Performs a 2D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void convolve( Kernel2D_S32 kernel, GrayU16 src, GrayI16 dst ) {
		dst.reshape(src.width,src.height);

		if( BOverrideConvolveImageNormalized.invokeNativeConvolve(kernel,src,dst) )
			return;

		if( kernel.width >= src.width || kernel.width >= src.height ) {
			ConvolveNormalizedNaive_SB.convolve(kernel, src, dst);
		} else {
			ConvolveImageNoBorder.convolve(kernel, src, dst, kernel.computeSum(), null);
			ConvolveNormalized_JustBorder_SB.convolve(kernel, src, dst);
		}
	}

	/**
	 * Performs a horizontal 1D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void horizontal( Kernel1D_S32 kernel, GrayU16 src, GrayI16 dst, ImageBorder_S32<GrayU16> bsrc ) {
		dst.reshape(src.width,src.height);

		//if( BOverrideConvolveImageNormalized.invokeNativeHorizontal(kernel,src,dst) )
		//	return;

		bsrc.setImage(src);

		if( kernel.width >= src.width ) {
			ConvolveNormalizedNaive_SB.horizontal(kernel, src, dst, bsrc);
		} else {
			ConvolveImageNoBorder.horizontal(kernel, src, dst, kernel.computeSum());
			ConvolveJustBorder_General_SB.horizontal(kernel, bsrc, dst, kernel.computeSum());
		}
	}

	/**
	 * Performs a vertical 1D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void vertical( Kernel1D_S32 kernel, GrayU16 src, GrayI16 dst, ImageBorder_S32<GrayU16> bsrc ) {
		dst.reshape(src.width,src.height);

		//if( BOverrideConvolveImageNormalized.invokeNativeVertical(kernel,src,dst) )
		//	return;

		bsrc.setImage(src);

		if( kernel.width >= src.height ) {
			ConvolveNormalizedNaive_SB.vertical(kernel, src, dst, bsrc);
		} else {
			ConvolveImageNoBorder.vertical(kernel, src, dst, kernel.computeSum(), null);
			ConvolveJustBorder_General_SB.vertical(kernel, bsrc, dst, kernel.computeSum());
		}
	}

	/**
	 * Performs a 2D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void convolve( Kernel2D_S32 kernel, GrayU16 src, GrayI16 dst, ImageBorder_S32<GrayU16> bsrc ) {
		dst.reshape(src.width,src.height);

		//if( BOverrideConvolveImageNormalized.invokeNativeConvolve(kernel,src,dst) )
		//	return;

		bsrc.setImage(src);

		if( kernel.width >= src.width || kernel.width >= src.height ) {
			ConvolveNormalizedNaive_SB.convolve(kernel, src, dst, bsrc);
		} else {
			ConvolveImageNoBorder.convolve(kernel, src, dst, kernel.computeSum(), null);
			ConvolveJustBorder_General_SB.convolve(kernel, bsrc, dst, kernel.computeSum());
		}
	}

	/**
	 * Performs a horizontal 1D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void horizontal( Kernel1D_S32 kernel, InterleavedU16 src, InterleavedI16 dst ) {
		dst.reshape(src.width,src.height);

		if( BOverrideConvolveImageNormalized.invokeNativeHorizontal(kernel,src,dst) )
			return;

		if( kernel.width >= src.width ) {
			ConvolveNormalizedNaive_IL.horizontal(kernel, src, dst);
		} else {
			ConvolveImageNoBorder.horizontal(kernel, src, dst, kernel.computeSum());
			ConvolveNormalized_JustBorder_IL.horizontal(kernel, src, dst);
		}
	}

	/**
	 * Performs a vertical 1D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void vertical( Kernel1D_S32 kernel, InterleavedU16 src, InterleavedI16 dst ) {
		dst.reshape(src.width,src.height);

		if( BOverrideConvolveImageNormalized.invokeNativeVertical(kernel,src,dst) )
			return;

		if( kernel.width >= src.height ) {
			ConvolveNormalizedNaive_IL.vertical(kernel, src, dst);
		} else {
			ConvolveImageNoBorder.vertical(kernel, src, dst, kernel.computeSum());
			ConvolveNormalized_JustBorder_IL.vertical(kernel, src, dst);
		}
	}

	/**
	 * Performs a 2D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void convolve( Kernel2D_S32 kernel, InterleavedU16 src, InterleavedI16 dst ) {
		dst.reshape(src.width,src.height);

		if( BOverrideConvolveImageNormalized.invokeNativeConvolve(kernel,src,dst) )
			return;

		if( kernel.width >= src.width || kernel.width >= src.height ) {
			ConvolveNormalizedNaive_IL.convolve(kernel, src, dst);
		} else {
			ConvolveImageNoBorder.convolve(kernel, src, dst, kernel.computeSum());
			ConvolveNormalized_JustBorder_IL.convolve(kernel, src, dst);
		}
	}

	/**
	 * Performs a horizontal 1D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void horizontal( Kernel1D_S32 kernel, GrayS32 src, GrayS32 dst ) {
		dst.reshape(src.width,src.height);

		if( BOverrideConvolveImageNormalized.invokeNativeHorizontal(kernel,src,dst) )
			return;

		if( kernel.width >= src.width ) {
			ConvolveNormalizedNaive_SB.horizontal(kernel, src, dst);
		} else {
			ConvolveImageNoBorder.horizontal(kernel, src, dst, kernel.computeSum());
			ConvolveNormalized_JustBorder_SB.horizontal(kernel, src, dst);
		}
	}

	/**
	 * Performs a vertical 1D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void vertical( Kernel1D_S32 kernel, GrayS32 src, GrayS32 dst ) {
		dst.reshape(src.width,src.height);

		if( BOverrideConvolveImageNormalized.invokeNativeVertical(kernel,src,dst) )
			return;

		if( kernel.width >= src.height ) {
			ConvolveNormalizedNaive_SB.vertical(kernel, src, dst);
		} else {
			ConvolveImageNoBorder.vertical(kernel, src, dst, kernel.computeSum(), null);
			ConvolveNormalized_JustBorder_SB.vertical(kernel, src, dst);
		}
	}

	/**
	 * Performs a 2D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void convolve( Kernel2D_S32 kernel, GrayS32 src, GrayS32 dst ) {
		dst.reshape(src.width,src.height);

		if( BOverrideConvolveImageNormalized.invokeNativeConvolve(kernel,src,dst) )
			return;

		if( kernel.width >= src.width || kernel.width >= src.height ) {
			ConvolveNormalizedNaive_SB.convolve(kernel, src, dst);
		} else {
			ConvolveImageNoBorder.convolve(kernel, src, dst, kernel.computeSum(), null);
			ConvolveNormalized_JustBorder_SB.convolve(kernel, src, dst);
		}
	}

	/**
	 * Performs a horizontal 1D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void horizontal( Kernel1D_S32 kernel, GrayS32 src, GrayS32 dst, ImageBorder_S32<GrayS32> bsrc ) {
		dst.reshape(src.width,src.height);

		//if( BOverrideConvolveImageNormalized.invokeNativeHorizontal(kernel,src,dst) )
		//	return;

		bsrc.setImage(src);

		if( kernel.width >= src.width ) {
			ConvolveNormalizedNaive_SB.horizontal(kernel, src, dst, bsrc);
		} else {
			ConvolveImageNoBorder.horizontal(kernel, src, dst, kernel.computeSum());
			ConvolveJustBorder_General_SB.horizontal(kernel, bsrc, dst, kernel.computeSum());
		}
	}

	/**
	 * Performs a vertical 1D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void vertical( Kernel1D_S32 kernel, GrayS32 src, GrayS32 dst, ImageBorder_S32<GrayS32> bsrc ) {
		dst.reshape(src.width,src.height);

		//if( BOverrideConvolveImageNormalized.invokeNativeVertical(kernel,src,dst) )
		//	return;

		bsrc.setImage(src);

		if( kernel.width >= src.height ) {
			ConvolveNormalizedNaive_SB.vertical(kernel, src, dst, bsrc);
		} else {
			ConvolveImageNoBorder.vertical(kernel, src, dst, kernel.computeSum(), null);
			ConvolveJustBorder_General_SB.vertical(kernel, bsrc, dst, kernel.computeSum());
		}
	}

	/**
	 * Performs a 2D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void convolve( Kernel2D_S32 kernel, GrayS32 src, GrayS32 dst, ImageBorder_S32<GrayS32> bsrc ) {
		dst.reshape(src.width,src.height);

		//if( BOverrideConvolveImageNormalized.invokeNativeConvolve(kernel,src,dst) )
		//	return;

		bsrc.setImage(src);

		if( kernel.width >= src.width || kernel.width >= src.height ) {
			ConvolveNormalizedNaive_SB.convolve(kernel, src, dst, bsrc);
		} else {
			ConvolveImageNoBorder.convolve(kernel, src, dst, kernel.computeSum(), null);
			ConvolveJustBorder_General_SB.convolve(kernel, bsrc, dst, kernel.computeSum());
		}
	}

	/**
	 * Performs a horizontal 1D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void horizontal( Kernel1D_S32 kernel, InterleavedS32 src, InterleavedS32 dst ) {
		dst.reshape(src.width,src.height);

		if( BOverrideConvolveImageNormalized.invokeNativeHorizontal(kernel,src,dst) )
			return;

		if( kernel.width >= src.width ) {
			ConvolveNormalizedNaive_IL.horizontal(kernel, src, dst);
		} else {
			ConvolveImageNoBorder.horizontal(kernel, src, dst, kernel.computeSum());
			ConvolveNormalized_JustBorder_IL.horizontal(kernel, src, dst);
		}
	}

	/**
	 * Performs a vertical 1D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void vertical( Kernel1D_S32 kernel, InterleavedS32 src, InterleavedS32 dst ) {
		dst.reshape(src.width,src.height);

		if( BOverrideConvolveImageNormalized.invokeNativeVertical(kernel,src,dst) )
			return;

		if( kernel.width >= src.height ) {
			ConvolveNormalizedNaive_IL.vertical(kernel, src, dst);
		} else {
			ConvolveImageNoBorder.vertical(kernel, src, dst, kernel.computeSum());
			ConvolveNormalized_JustBorder_IL.vertical(kernel, src, dst);
		}
	}

	/**
	 * Performs a 2D normalized convolution across the image.
	 *
	 * @param src The original image. Not modified.
	 * @param dst Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 */
	public static void convolve( Kernel2D_S32 kernel, InterleavedS32 src, InterleavedS32 dst ) {
		dst.reshape(src.width,src.height);

		if( BOverrideConvolveImageNormalized.invokeNativeConvolve(kernel,src,dst) )
			return;

		if( kernel.width >= src.width || kernel.width >= src.height ) {
			ConvolveNormalizedNaive_IL.convolve(kernel, src, dst);
		} else {
			ConvolveImageNoBorder.convolve(kernel, src, dst, kernel.computeSum());
			ConvolveNormalized_JustBorder_IL.convolve(kernel, src, dst);
		}
	}

}
